/**
 * 容器类，抽象类，不能直接实例化
 * @author zzhanglin
 * @return {DisplayObjectContainer}
 */
DisplayObjectContainer = function()
{
	InteractiveObject.call(this);

	this.className="DisplayObjectContainer"; //类名
	this.mouseChildren = true ; //子元素的是否支持鼠标事件
	
	this._children = []; //子元素
};
FLASH.extend( DisplayObjectContainer , InteractiveObject ); //继承自InteractiveObject

//===================设置getter/setter====================

//重写宽高的getter
DisplayObjectContainer.prototype.getWidth = function(){ return this.getBounds(this._parent).width; };
DisplayObjectContainer.prototype.getHeight = function(){ return this.getBounds(this._parent).height; };
//获得子元素的数量
DisplayObjectContainer.prototype.getNumChildren = function(){ return this._children.length ; } ;

//================================================

/**
 * 返回一个矩形，该矩形定义相对于 targetCoordinateSpace 对象坐标系的显示对象区域
 * @param targetCoordinateSpace
 * @return 
 */
DisplayObjectContainer.prototype.getBounds = function(targetCoordinateSpace)
{
	var LEN = this._children.length;
	if (LEN == 0){
	    var position = this._localModelMatrix.transformPoint( this._x, this._y );
	    return new Rectangle(position.x, position.y,0,0);
	}
	else if (LEN == 1)
	{
	    return this._children[0].getBounds(targetCoordinateSpace);
	}
	else
	{
	    var minX = Number.MAX_VALUE, maxX = -Number.MAX_VALUE;
	    var minY = Number.MAX_VALUE, maxY = -Number.MAX_VALUE;
	    for (var i=0; i<LEN; ++i)
	    {
	        var childBounds = this._children[i].getBounds(targetCoordinateSpace);
	        minX = Math.min(minX, childBounds.x);
	        maxX = Math.max(maxX, childBounds.x + childBounds.width);
	        minY = Math.min(minY, childBounds.y);
	        maxY = Math.max(maxY, childBounds.y + childBounds.height);                    
	    }
	    return new Rectangle(minX, minY, maxX-minX, maxY-minY);
	}
};

/**
 * 添加子元素
 * @param child
 * @param 添加的元素
 */
DisplayObjectContainer.prototype.addChild = function(child)
{	
	 return this.addChildAt(child,  this.getNumChildren() );
};

/**
 * 通过索引移除子元素
 * @param child
 * @param index
 * @param 添加的元素
 */
DisplayObjectContainer.prototype.addChildAt =function( child , index )
{
	if (index >= 0 && index <= this.getNumChildren())
    {
        child._removeFromParent( false );
        this._children.splice(index, 0, child);
        child._parent = this ;
        child._stage = FlashCore.stage ;
        if(this.hasEventListener(Event.ADDED))child.dispatchEvent(new Event(Event.ADDED));                
        if (this._stage) child._dispatchEventOnChildren(new Event(Event.ADDED_TO_STAGE));
    }
    return child;
};
/**
 * 移除对象
 * @param child
 * @param dispose boolean型 
 * @returns 此删除的对象
 */
DisplayObjectContainer.prototype.removeChild =  function(child, dispose )
{
    var childIndex = this.getChildIndex(child);
    if (childIndex != -1) return this.removeChildAt(childIndex, dispose);
    return null ;
};

/**
 * 通过索引位置来移除子元素
 * @param index 子元素索引
 * @dispose 是否调用dispose
 * @return 此删除的对象
 */
DisplayObjectContainer.prototype.removeChildAt = function(index , dispose )
{
	dispose = dispose==undefined?false:dispose;
    if (index >= 0 && index < this._children.length )
    {
        var child = this._children[index];
        if(this.hasEventListener(Event.REMOVED))child.dispatchEvent(new Event(Event.REMOVED));
        if (this._stage)  child._dispatchEventOnChildren(new Event(Event.REMOVED_FROM_STAGE));
        child._parent=  null ;
        child._stage = null ;
        this._children.splice(index, 1);
        if (dispose) child.dispose();
        return child;
    }
    return null ;
};

/**
 * 移除所有的子元素
 * @param dispose 是否执行dispose
 */
DisplayObjectContainer.prototype.removeAllChildren = function( dispose )
{
	while( this.getNumChildren()>0){
		this.removeChildAt(0,dispose);
	}
};

/**
 * 通过索引来获取对象
 * @param index索引
 */
DisplayObjectContainer.prototype.getChildAt = function(index)
{
    if (index >= 0 && index < this._children.length )
        return this._children[index];
};

/**
 * 通过名字来获取子元素
 * @param name  子元素的名字
 * @return 
 */
DisplayObjectContainer.prototype.getChildByName = function(name)
{
	var LEN = this._children.length ;
	for( var i=0 ; i<LEN ;++i){
		if( this._children[i].name == name ){
			return this._children[i] ;
		}
	}
	return null ;
};

/**
 * 获取对象的索引
 * @param child
 * @return 索引
 */
DisplayObjectContainer.prototype.getChildIndex = function (child )
{
    return this._children.indexOf(child);
};

/**
 * 设置索引
 * @param child
 * @param index
 */
DisplayObjectContainer.prototype.setChildIndex = function(child, index)
{
    var oldIndex = this.getChildIndex(child);
    if (oldIndex >-1 ){
        this._children.splice(oldIndex, 1);
        this._children.splice(index, 0, child);
    } 
};

/**
 * 切换深度
 * @param child1
 * @param child2
 */
DisplayObjectContainer.prototype.swapChildren = function(child1, child2 )
{
    var index1 = this.getChildIndex(child1);
    var index2 = this.getChildIndex(child2);
    if (index1 == -1 || index2 == -1) return;
    this.swapChildrenAt(index1, index2);
} ;

/**
 * 切换深度
 * @param index1
 * @param index2
 */
DisplayObjectContainer.prototype.swapChildrenAt = function(index1, index2 )
{
    var child1 = this.getChildAt(index1);
    var child2 = this.getChildAt(index2);
    this._children[index1] = child2;
    this._children[index2] = child1;
};

/**
 * 是否包含一个子元素
 * @param child 子对象
 * @return 包含返回true,否则返回false
 */
DisplayObjectContainer.prototype.contains = function(child)
{
    if (child == this) return true;
    var LEN = this._children.length ;
    for( var i = 0 ; i<LEN ; ++i){
    	if( this._children[i] = child ){
    		return true ;
    	}
    }
    return false ;
} ;
/**
 * 释放资源
 */
DisplayObjectContainer.prototype.dispose = function()
{
	DisplayObject.prototype.dispose.call(this);
	var LEN = this._children.length ;
	for( var i= 0 ; i<LEN ; ++i){
		this._children[i].dispose();
	}
	this._children = null ;
};

//================私有方法============================
//==================================================
/**
 * 游戏的主循环
 */
DisplayObjectContainer.prototype._gameLoop = function(globalAlpha , context , parentMatrixChanged)
{
	DisplayObject.prototype._gameLoop.call(this , globalAlpha , context , parentMatrixChanged );
	
	globalAlpha*=this._alpha ;
	var LEN = this._children.length ;
	var child ;
	for (var i= 0  ; i<LEN ; ++i )
	{
		child = this._children[i];
		child._gameLoop(globalAlpha , context , parentMatrixChanged);
	}
};
/**
 * 渲染图形
 *@param globalAlpha 全局透明度
 *@param context 
 *@param parentMatrixchanged
 */
DisplayObjectContainer.prototype._render = function( globalAlpha , context , parentMatrixChanged )
{
	globalAlpha*=this._alpha ;
	
	var myMatrixChanged = false;
	if(this._invalidateMatrix) {
		this._updateLocalMatrix();
		myMatrixChanged = true;
	}
	if(parentMatrixChanged || myMatrixChanged) {
		this._updateWorldMatrix();
		myMatrixChanged = true;
	}
	this._draw(globalAlpha , context );
	
	//遍历子元素
	var LEN = this._children.length ;
	var child ;
	for (var i= 0  ; i<LEN ; ++i )
	{
		child = this._children[i];
		if (child._alpha != 0.0 && child.visible && child._scaleX != 0 && child._scaleY != 0)
        {
            child._render(globalAlpha , context , myMatrixChanged );
        }
	}
};

/**
 * 重写:子元素抛出事件
 * @param event 事件
 */
DisplayObjectContainer.prototype._dispatchEventOnChildren = function(event)
{
	 var listeners = [] ;
     this._getChildEventListeners(this, event._type, listeners);
     var LEN = listeners.length ;
     for( var i=0 ; i<LEN ; ++i ){
		 listeners[i].dispatchEvent(event);
     }
};

/**
 * 获取子元素所有侦听过此eventType的对象
 */
DisplayObjectContainer.prototype._getChildEventListeners = function(object,eventType,listeners)
{        
	if (object.hasEventListener(eventType)){
		listeners.push(object);
	}
	if (object instanceof DisplayObjectContainer )
	{
		var LEN = object._children.length ;
		for( var i= 0 ; i<LEN ; ++i){
			this._getChildEventListeners(object._children[i], eventType, listeners);
		}
	}
};


//=====处理子元素的鼠标事件====================================

/**
 * 鼠标移动
 * @param localX 相对canvas的鼠标坐标位置 
 * @param localY 相对canvas的鼠标坐标位置
 * @param 当前对象是否抛出了mouseMove事件
 */
DisplayObjectContainer.prototype._onMouseMove = function( localX, localY, ctrlKey, altKey,shiftKey, buttonDown, delta )
{
	if(!this.mouseChildren) return false;
	
	var result = false ;
	var child ;
	var LEN = this._children.length ;
	for( var i= 0 ; i<LEN ; ++i){
		child = this._children[i];
		if(child instanceof InteractiveObject && child._onMouseMove(localX-this._x , localY-this._y , ctrlKey, altKey,shiftKey, buttonDown, delta) )
		{
			//子对象的鼠标事件执行成功
			result = true ;
			break ;
		}
	}
	if(result==false){
		return InteractiveObject.prototype._onMouseMove.call( this , localX, localY, ctrlKey, altKey,shiftKey, buttonDown, delta );
	}
	return true ;
};
/**
 * 鼠标按下
 */
DisplayObjectContainer.prototype._onMouseDown = function( ctrlKey, altKey,shiftKey, buttonDown, delta )
{
	if(!this.mouseChildren) return false;
	
	var result = false ;
	var child ;
	var LEN = this._children.length ;
	for( var i= 0 ; i<LEN ; ++i){
		child = this._children[i];
		if(child instanceof InteractiveObject &&child._onMouseDown(ctrlKey, altKey,shiftKey, buttonDown, delta) )
		{
			//子对象的鼠标事件执行成功
			result = true ;
			break ;
		}
	}
	return result;
};
/**
 * 鼠标弹起
 */
DisplayObjectContainer.prototype._onMouseUp = function( ctrlKey, altKey,shiftKey, buttonDown, delta )
{
	if(!this.mouseChildren) return false;
	
	var result = false ;
	var child ;
	var LEN = this._children.length ;
	for( var i= 0 ; i<LEN ; ++i){
		child = this._children[i];
		if(child instanceof InteractiveObject &&child._onMouseUp(ctrlKey, altKey,shiftKey, buttonDown, delta) )
		{
			//子对象的鼠标事件执行成功
			result = true ;
			InteractiveObject.prototype._onMouseClick.call(this,ctrlKey, altKey,shiftKey, buttonDown, delta);
			break ;
		}
	}
	return result;
};
/**
 * 鼠标单击
 */
DisplayObjectContainer.prototype._onMouseClick = function( ctrlKey, altKey,shiftKey, buttonDown, delta )
{
	if(!this.mouseChildren) return false;
	
	var result = false ;
	var child ;
	var LEN = this._children.length ;
	for( var i= 0 ; i<LEN ; ++i){
		child = this._children[i];
		if(child instanceof InteractiveObject &&child._onMouseClick(ctrlKey, altKey,shiftKey, buttonDown, delta) )
		{
			//子对象的鼠标事件执行成功
			result = true ;
			break ;
		}
	}
	return result;
};
/**
 * 鼠标在上面
 */
DisplayObjectContainer.prototype._onMouseOver= function( ctrlKey, altKey,shiftKey, buttonDown, delta )
{
	if(!this.mouseChildren) return false;
	
	var result = false ;
	var child ;
	var LEN = this._children.length ;
	for( var i= 0 ; i<LEN ; ++i){
		child = this._children[i];
		if(child instanceof InteractiveObject &&child._onMouseOver(ctrlKey, altKey,shiftKey, buttonDown, delta) )
		{
			//子对象的鼠标事件执行成功
			result = true ;
			break ;
		}
	}
	return result;
};
/**
 * 鼠标移出此对象
 */
DisplayObjectContainer.prototype._onMouseOut = function( ctrlKey, altKey,shiftKey, buttonDown, delta )
{
	if(!this.mouseChildren) return false;
	
	var result = false ;
	var child ;
	var LEN = this._children.length ;
	for( var i= 0 ; i<LEN ; ++i){
		child = this._children[i];
		if(child instanceof InteractiveObject &&  child._onMouseOut(ctrlKey, altKey,shiftKey, buttonDown, delta) )
		{
			//子对象的鼠标事件执行成功
			result = true ;
			break ;
		}
	}
	return result;
};